<script lang="ts">
export default {
  name: 'Study7StuDemo3'
}
</script>

<template>
  <h2>生命周期函数-onUpdated</h2>
  <div class="note">
    <p>应用场景：</p>
    <p>1. 监听数据变化并执行特定操作：当某些响应式数据更新后执行额外逻辑。</p>
    <p>2. 处理 DOM 变更后的操作：在 DOM 发生更新时进行额外的 DOM 操作，如滚动条处理。</p>
    <p>3. 监测子组件变化后的操作：在子组件的状态或 UI 发生变化时触发额外的逻辑。</p>
  </div>

  <hr class="hr-style" />
  <h3>监听数据变化后滚动到底部</h3>
  <div class="group">
    <div ref="messageBox" class="message-box">
      <div v-for="message in messages" :key="message.id">{{ message.text }}</div>
    </div>
    <button @click="addMessage">Add Message</button>
  </div>

  <hr class="hr-style" />
  <h3>数据变化后执行动画</h3>
  <div class="group">
    <p ref="numberDisplay" class="number">{{ number }}</p>
    <button @click="increaseNumber">Increase</button>
  </div>

  <hr class="hr-style" />
  <h3>监听子组件变化并调整布局</h3>
  <div class="group">
    <SonDemo1 ref="sonDemo1"></SonDemo1>
  </div>
</template>

<script setup lang="ts">
import { onUpdated, ref, type Ref } from 'vue'
import SonDemo1 from './components/SonDemo1.vue'

/**
 * 监听数据变化后滚动到底部
 * 1)场景说明: 当消息列表 messages 更新时，onUpdated 钩子会触发滚动到消息列表的底部。这种情况常用于聊天或动态数据加载的场景。
 */
const messages = ref([
  { id: 1, text: 'Hello' },
  { id: 2, text: 'World' }
])
const addMessage = () => {
  messages.value.push({
    id: messages.value.length + 1,
    text: 'New message'
  })
}
let messageBox: Ref<HTMLElement>
onUpdated(() => {
  // 数据更新后滚动到底部
  if (messageBox.value) {
    messageBox.value.scrollTop = messageBox.value.scrollHeight
  }
})

/**
 * 数据变化后执行动画
 * 1)场景说明: 每次数字 number 变化时，onUpdated 钩子会触发一个放大的动画效果。这样的场景可以用于显示变化的统计数据或计数器时，增强用户体验。
 */
const number = ref(0)
const increaseNumber = () => {
  number.value++
}

// 监听p元素的数据更新
const numberDisplay = ref()

onUpdated(() => {
  // 在数据变化后给数字添加动画
  if (numberDisplay.value) {
    numberDisplay.value.style.transition = 'transform 0.2s'
    numberDisplay.value.style.transform = 'scale(1.9)'
    setTimeout(() => {
      numberDisplay.value.style.transform = 'scale(1)'
    }, 500)
  }
})

/**
 * 监听子组件变化并调整布局
 * 1)场景说明: 当子组件 sonDemo1 的内容发生变化时，onUpdated 钩子可以用来捕获这些变化并对父组件进行相应的布局调整。这种场景常用于父组件根据子组件的动态变化进行响应式布局调整。
 */
const sonDemo1 = ref()
console.log(sonDemo1.value)
onUpdated(() => {
  console.log(sonDemo1.value)

  // 当子组件的内容更新时，调整父组件的布局
  if (sonDemo1.value) {
    console.log('Child component updated, adjusting layout...')
    // 假设这里根据子组件的内容调整父组件的布局
  }
})
</script>

<style scoped>
.number {
  font-size: 10px;
}
.message-box {
  height: 100px;
  overflow-y: auto;
  border: 1px solid #ccc;
}
body {
  padding: 20px;
}
h2 {
  color: red;
}
h3 {
  color: rgb(220, 85, 85);
}
h4 {
  color: skyblue;
}
.hr-style {
  border: 3px solid gold;
  margin: 20px 0;
}
.group {
  border: 4px solid rgb(102, 215, 85);
  margin: 10px;
  padding: 10px;
}
.note {
  margin: 10px;
  padding: 10px;
  border: 3px solid rgb(221, 121, 202);
}
.note p {
  color: rgb(226, 106, 204);
  font-weight: bold;
}
</style>
